//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Notification;
using OpenLS.Core.Serialization;
using OpenLS.Spreadsheet.Parsing;

namespace OpenLS.Spreadsheet
{
    public class Pane :ViewModelBase, IOfficeXmlSerializable
    {
        private PaneType _activePane = PaneType.TopLeft;
        private double? _height;
        private PaneState _state;
        private string _topLeftCell;
        private double? _width;

        public double? Width
        {
            get { return _width; }
            set { _width = value; }
        }

        public double? Height
        {
            get { return _height; }
            set { _height = value; }
        }

        private int? _rowCount;
        public int? RowCount
        {
            get { return _rowCount; }
            set { _rowCount = value; }
        }

        private int? _columnCount;
        public int? ColumnCount
        {
            get { return _columnCount; }
            set { _columnCount = value; }
        }


        internal string TopLeftCell
        {
            get { return _topLeftCell; }
            set { _topLeftCell = value; }
        }

        public PaneType ActivePane
        {
            get { return _activePane; }
            set { _activePane = value; }
        }

        public PaneState State
        {
            get { return _state; }
            set
            {
                _state = value;
                notifyPropertyChanged("State");
            }
        }


        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (ReadContext c = context.Read("pane"))
            {
                _state = c.GetOptionalEnum("state", PaneState.Split);
                double? d = c.GetOptionalDouble("xSplit");
                TopLeftCell = c.GetOptionalString("topLeftCell");
                CellAddress? ca = null;
                if (TopLeftCell != null)
                {
                    CellAddress ca2;
                    if (new A1NamingConvention().TryParse(TopLeftCell, out ca2))
                        ca = ca2;
                }
                if (d != null)
                {
                    switch (_state)
                    {
                        case PaneState.Frozen:
                        case PaneState.FrozenSplit:
                            ColumnCount= (int) Math.Round(d.Value);
                            break;
                        case PaneState.Split:
                            _width = PointsToPixelConverter.ToPixel(d.Value/20);
                            break;
                        default:
                            throw new NotSupportedException();
                    }
                }
                d = c.GetOptionalDouble("ySplit");
                if (d != null)
                {
                    switch (_state)
                    {
                        case PaneState.Frozen:
                        case PaneState.FrozenSplit:
                            RowCount= (int) Math.Round(d.Value);
                            break;
                        case PaneState.Split:
                            _height = PointsToPixelConverter.ToPixel(d.Value/20);
                            break;
                        default:
                            throw new NotSupportedException();
                    }
                }
                _activePane = c.GetOptionalEnum("activePane", PaneType.TopLeft);
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            if (IsDefault())
                return;
            using (WriteContext c = context.Write("pane"))
            {
                switch (State)
                {
                    case PaneState.Frozen:
                    case PaneState.FrozenSplit:
                        Worksheet worksheet = context.GetData<Worksheet>();
                        c.SetOptionalDouble("xSplit", ColumnCount);
                        c.SetOptionalDouble("ySplit", RowCount);
                        break;
                    case PaneState.Split:
                        if (Width != null)
                            c.SetOptionalDouble("xSplit", PointsToPixelConverter.ToPoint(Width.Value*20));
                        if (Height != null)
                            c.SetOptionalDouble("ySplit", PointsToPixelConverter.ToPoint(Height.Value*20));
                        break;
                    default:
                        throw new NotImplementedException();
                }
                c.SetOptionalString("topLeftCell", TopLeftCell);
                c.SetOptionalEnum("activePane", _activePane, PaneType.TopLeft);
                c.SetOptionalEnum("state", _state, PaneState.Split);
            }
        }

        #endregion

        private bool IsDefault()
        {
            switch (State)
            {
                case PaneState.Frozen:
                case PaneState.FrozenSplit:
                    return false;
                case PaneState.Split:
                    if (Width != null || Height != null)
                        return false;
                    break;
            }
            if (TopLeftCell != null)
                return false;
            if (_activePane != PaneType.TopLeft) return false;
            if (_state != PaneState.Split) return false;
            return true;
        }


    }
}